package com.zyx.utils;

import com.zyx.netty.codec.DynamicHttpCodec;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.net.InetAddress;
import java.util.concurrent.CountDownLatch;

import static com.zyx.constants.Constants.HTTP_METHOD_POST;


/**
 * 描述说明:
 *
 * @author DQing
 * @version 1.0
 * @className DynamicMsgUtils
 * @date 2020/4/2 12:00
 */
@Slf4j
public class DynamicMsgUtils {

    /**
     * 响应报文
     * @param channel      响应报文的通达
     * @param msg          报文内容
     */
    public static void responseMsg(Channel channel,String msg,boolean toDevice){
        ChannelPipeline pipeline = channel.pipeline();
        DynamicHttpCodec.responseHandler(pipeline,false);
        responseSend(channel,msg,toDevice);
    }

    /**
     * FullHttpResponse报文响应
     * @param channel  响应通道
     * @param msg      响应报文内容
     * @param toDevice 是否响应至device
     */
    public static void responseSend(Channel channel, String msg,boolean toDevice){
        log.info(" 发送响应报文：channel={},msg={}",channel,msg);
        FullHttpResponse resp;
        if(StringUtils.isEmpty(msg)){
            resp = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
                    HttpResponseStatus.OK);
        }else{
            resp = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
                    HttpResponseStatus.OK,
                    Unpooled.copiedBuffer(msg, CharsetUtil.UTF_8));
            resp.headers().set(HttpHeaderNames.CONTENT_LENGTH,msg.getBytes().length);
        }
        resp.headers()
                .set(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON)
                .set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE)
                .set(HttpHeaderNames.X_FRAME_OPTIONS, "SAMEORIGIN");
        log.info("请求报文头：{}, 请求报文内容：{}",resp.headers(),resp.content().toString(CharsetUtil.UTF_8));
        ChannelFuture cf = channel.writeAndFlush(resp);
        if(!toDevice){
            cf.addListener(ChannelFutureListener.CLOSE);
        }
    }


    /**
     * 响应报文为请求报文
     * @param channel  报文处理通道
     * @param msg      报文处理消息
     * @param uri      请求报文URI
     * @param methodType  请求报文类型
     */
    public static void requestMsg(Channel channel,String msg,String uri,String methodType){
        ChannelPipeline pipeline = channel.pipeline();
        DynamicHttpCodec.responseHandler(pipeline,true);
        requestSend(channel,msg,uri,methodType);
    }

    /**
     * FullHttpRequest报文响应
     * @param channel  响应通道
     * @param msg      响应内容
     * @param uri      响应URI
     * @param methodType 响应报文类型
     */
    private static void requestSend(Channel channel,String msg,String uri,String methodType){
        log.info("# 封装请求外部报文");
        FullHttpRequest request;
        HttpMethod method = new HttpMethod(methodType);
        if(StringUtils.isEmpty(msg)){
            request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, method,uri);
        }else{
            request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, method,
                    uri,Unpooled.copiedBuffer(msg, CharsetUtil.UTF_8));
            request.headers().
                    set(HttpHeaderNames.CONTENT_LENGTH, msg.getBytes().length);
        }
        request.headers().
                set(HttpHeaderNames.CACHE_CONTROL,HttpHeaderValues.NO_CACHE).
                set(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON).
                set(HttpHeaderNames.CONNECTION,HttpHeaderValues.KEEP_ALIVE).
                set(HttpHeaderNames.ACCEPT,"*/*").
                set(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.GZIP_DEFLATE);
        //获取HOST
        String hostAddress = "";
        try{
            InetAddress address = InetAddress.getLocalHost();
            hostAddress = address.getHostAddress();
        }catch (Exception e){
            log.error(" 获取当前服务器Host失败:{}",e.getMessage());
        }
        if(!StringUtils.isEmpty(hostAddress)){
            request.headers().
                    set(HttpHeaderNames.HOST, hostAddress);
        }
        log.info("请求通道channel={}, 请求地址uri={}, 请求报文头：{}, 请求报文内容：{}",channel,uri,request.headers(),request.content().toString(CharsetUtil.UTF_8));
        channel.writeAndFlush(request);
    }


    /**
     * 响应至业务平台的报文
     * @param channel
     * @param msg
     */
    public static void toBusiResponse(Channel channel, String msg){
        FullHttpResponse resp = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
                HttpResponseStatus.OK,
                Unpooled.copiedBuffer(msg, CharsetUtil.UTF_8));
        resp.headers()
                .set(HttpHeaderNames.CONTENT_LENGTH,msg.getBytes(CharsetUtil.UTF_8).length)
                .set(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON)
                .set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE)
                .set(HttpHeaderNames.X_FRAME_OPTIONS, "SAMEORIGIN");
        log.info("请求报文头：{}, 请求报文内容：{}",resp.headers(),resp.content().toString(CharsetUtil.UTF_8));
        ChannelFuture cf = channel.writeAndFlush(resp);
        cf.addListener(ChannelFutureListener.CLOSE);
    }
}
